package br.com.wepa.webapps.orca.controle.validator;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericTypeValidator;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.validator.Resources;

public class NumberValidator {

	/**
	 * 
	 * @param bean
	 * @param va
	 * @param field
	 * @param errors
	 * @param validator
	 * @param request
	 * @return
	 */
	public static boolean validateDouble(Object bean, ValidatorAction va,
			Field field, ActionMessages errors, Validator validator,
			HttpServletRequest request) {

		DecimalFormatSymbols formatter = ((DecimalFormat) DecimalFormat
				.getInstance(request.getLocale())).getDecimalFormatSymbols();
		try {
			Collection values = ValidatorUtil.getCollection(bean, field
					.getProperty());
			for (Object value : values) {
				if (!validateDouble(value, field, formatter)) {
					ValidatorUtil.addError(va, field, errors, validator,
							request);
					return false;
				}
			}
			return true;

		} catch (Exception e) {
			e.printStackTrace();
			ValidatorUtil.addError(va, field, errors, validator, request);
			return false;
		}
	}

	/**
	 * 
	 * @param bean
	 * @param field
	 * @param formatter
	 * @return
	 */
	private static boolean validateDouble(Object bean, Field field,
			DecimalFormatSymbols formatter) {

		if (bean == null)
			return true;
		String value = ValidatorUtil.toString(bean, field);
		if (GenericValidator.isBlankOrNull(value))
			return true;

		String groupSimbol = "" + formatter.getGroupingSeparator();
		String decimalSimbol = "" + formatter.getDecimalSeparator();
		Object result = convertDouble(value, decimalSimbol, groupSimbol);

		return (result != null);
	}

	/**
	 * Checks if the field can safely be converted to an int primitive.
	 * 
	 * @param bean
	 *            The bean validation is being performed on.
	 * @param va
	 *            The <code>ValidatorAction</code> that is currently being
	 *            performed.
	 * @param field
	 *            The <code>Field</code> object associated with the current
	 *            field being validated.
	 * @param errors
	 *            The <code>ActionMessages</code> object to add errors to if
	 *            any validation errors occur.
	 * @param validator
	 *            The <code>Validator</code> instance, used to access other
	 *            field values.
	 * @param request
	 *            Current request object.
	 * @return true if valid, false otherwise.
	 */
	public static boolean validateInteger(Object bean, ValidatorAction va,
			Field field, ActionMessages errors, Validator validator,
			HttpServletRequest request) {

		try {
			Collection values = ValidatorUtil.getCollection(bean, field
					.getProperty());

			for (Object obj : values) {
				if (!isInteger(obj)) {
					errors.add(field.getKey(), Resources.getActionMessage(
							validator, request, va, field));
					return Boolean.FALSE;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			errors.add(field.getKey(), Resources.getActionMessage(validator,
					request, va, field));
			return Boolean.FALSE;
		}
		return Boolean.TRUE;

	}

	private static boolean isInteger(Object obj) {
		String value = obj == null ? null : obj.toString();
		if (GenericValidator.isBlankOrNull(value)) {
			return true;
		}
		Integer resp = GenericTypeValidator.formatInt(value);
		return resp != null;
	}

	public static Object convertDouble(String value, String decimalSimbol,
			String groupSimbol) {
		value = (".".equals(decimalSimbol)) ? value : value.replace(".", "");
		value = value.replace(groupSimbol, ""); // tira os grupos
		value = value.replace(decimalSimbol, "."); // muda o ident. de decimal

		return GenericTypeValidator.formatDouble(value);
	}
}
